package cn.monkey.io.transport.netty;

import cn.monkey.io.transport.core.ExchangeContext;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

public class DefaultChannelGroupExchangeContext implements ExchangeContext {

    private static final Logger log = LoggerFactory.getLogger(DefaultChannelGroupExchangeContext.class);
    protected final ChannelGroup channelGroup;

    public DefaultChannelGroupExchangeContext(ChannelGroup channelGroup) {
        this.channelGroup = channelGroup;
    }

    @Override
    public <T> T setAttribute(String key, T val) {
        AttributeKey<T> attributeKey = AttributeKey.valueOf(key);
        T old = null;
        for (Channel channel : this.channelGroup) {
            T andSet = channel.attr(attributeKey).getAndSet(val);
            if (old == null) {
                old = andSet;
                continue;
            }
            if (andSet != null && !andSet.equals(old)) {
                if (log.isDebugEnabled()) {
                    log.debug("channel: {} attr: {} is different with others: {}", channel.id(), key, andSet);
                }
            }
        }
        return old;
    }

    @Override
    public <T> T getAttribute(String key) {
        AttributeKey<T> attributeKey = AttributeKey.valueOf(key);
        return this.channelGroup.stream().map(channel -> channel.attr(attributeKey).get())
                .filter(Objects::nonNull)
                .findFirst().orElse(null);
    }
}
